# ommbot/fleet.py
#
#

""" fleet is a list of bots """

__copyright__ = 'this file is in the public domain'

import ommbot.generic
import ommbot.ircevent
import ommbot.persist
import ommbot.thr
import ommbot.bot
import ommbot.world
import Queue
import os

class Fleet(object):

    """ contains multiple bots (list of bots) """

    def __init__(self, path):
        self.botdata = ommbot.persist.Persist(path + os.sep + 'fleet')
        if not self.botdata.data:
            self.botdata.data = {}
        self.bots = []

    def clone(self, ievent=None):
        newbots = []
        for i in self.bots:

            newbot = ommbot.bot.Bot(i.name, i.datadir, i.owner)
            i.shutdown()
            ommbot.world.log.log(10, 'fleet', 'making clone of %s' % i.name)
            newbot.clone(i)
            newbot.start()
            if ievent and i == ievent.bot:
                ievent.bot = newbot
            newbots.append(newbot)
        self.bots = newbots
        return len(newbots)
            
    def size(self):
        """ return number of bots """
        return len(self.bots)

    def start(self):
        """ startup the bots """
        for i, j in self.botdata.data.iteritems():
            self.add(i, *j)

    def save(self):
        """ save fleet data and call save on all the bots """
        try:
            self.botdata.save()
        except Exception, ex:
            ommbot.generic.handle_exception()

    def list(self):
        """ return list of bot names """
        result = []
        for i in self.bots:
            result.append(i.name)
        return result

    def stopall(self):
        """ return bot by name """
        for i in self.bots:
            try:
                i.shutdown()
            except:
                pass

    def byname(self, name):
        """ return bot by name """
        name = name.lower()
        for i in self.bots:
            if name == i.name:
                return i

    def addbot(self, bot):
         if self.byname(bot.name):
             return
         self.botdata.data[bot.name] = (bot.name, bot.datadir, bot.owner, \
                                            bot.nick, bot.server, bot.port, \
                                            bot.password, bot.ipv6)
         self.botdata.save()
         self.bots.append(bot)

    def add(self, name, datadir, owner, nick, server, port=6667, \
                password=False, ipv6=False):
        """ create bot and call connect """
        name = name.lower()
        try:
            bot = ommbot.bot.Bot(name, datadir, owner)
            self.bots.append(bot)
            self.botdata.save()
            ommbot.thr.start_new_thread(bot.connect, (nick, server, port, \
                                            password, ipv6))
        except Exception, ex:
            ommbot.generic.handle_exception()

    def connect(self, name):
        """ connect bot to irc server"""
        name = name.lower()
        for i in self.bots:
            if i.name == name:
                try:
                    data = self.botdata.data[name]
                except:
                    return
                ommbot.thr.start_new_thread(i.connect, data)
                return 1

    def delete(self, name):
        """ delete bot with name from fleet """
        name = name.lower()
        for i in self.bots:
            if i.name == name:
                i.exit()
                try:
                    del self.botdata.data[name]
                    self.botdata.save()
                except:
                    pass
                self.remove(i)
                return 1

    def remove(self, bot):
        """ delete bot by object """
        self.bots.remove(bot)

    def exit(self, name):
        """ call exit on all bots """
        name = name.lower()
        for i in self.bots:
            if i.name == name:
                try:
                    i.exit()
                except:
                    pass
                return 1

    def exitall(self):
        """ call exit on all bots """
        for i in self.bots:
            try:
                i.exit()
            except Exception, ex:
                ommbot.generic.handle_exception()

    def cmnd(self, ievent, name, cmnd):
        """ do command on a bot by name """
        name = name.lower()
        bot = self.byname(name)
        if not bot:
            return 0
        j = ommbot.ircevent.Ircevent()
        j.copyin(ievent)
        j.txt = cmnd
        q = Queue.Queue()
        j.queues = [q]
        j.speed = 3
        if ommbot.world.plugs:
            ommbot.world.plugs.trydispatch(bot, j)
        result = ommbot.generic.waitforqueue(q)
        for res in result:
            ievent.reply("[%s] %s" % (bot.name, res))

    def cmndall(self, ievent, cmnd):
        """ do a command on all bots """
        threads = []
        for i in self.bots:
            thread = ommbot.thr.start_new_thread(self.cmnd, (ievent, i.name, \
                                                     cmnd))
            threads.append(thread)
        for i in threads:
            i.join(10)
